﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Biblioteca.Models;
using System.Data;
using System.Web.Security;
using Biblioteca.Interfaces;

namespace Biblioteca.Controllers
{
    
    public class CuentaController : Controller
    {
        private BibliotecaStore db;
        private ICuentaUsuario CuentaRepo;
        private IUsuario UsuarioRepo;

        public CuentaController(ICuentaUsuario cr,IUsuario ur, BibliotecaStore data)
        {
            this.CuentaRepo = cr;
            this.UsuarioRepo = ur;
            this.db = data;
        }
        //
        // GET: /Cuenta/

        public ActionResult Index()
        {
            return View(CuentaRepo.getAll());
        }

        //
        // GET: /Cuenta/Details/5

        public ActionResult Details(int id)
        {

            return View();
        }

        //
        // GET: /Cuenta/Create

        public ActionResult Create()
        {

            ViewData["Users"] = UsuarioRepo.getAll();
            return View();
        } 

        //
        // POST: /Cuenta/Create

        [HttpPost]
        public ActionResult Create(Cuenta c)
        {
            try
            {
                
                Int32 user = Int32.Parse(Request["User"]);

                CuentaRepo.crearCuentaUsuario(c, user);
                return RedirectToAction("Index");
            }
            catch
            {
                return new HttpNotFoundResult();;
            }
        }
        
        //
        // GET: /Cuenta/Edit/5
 
        public ActionResult Edit(int id)
        {
            Cuenta cuenta = CuentaRepo.getSingle(id);
            return View(cuenta);
        }

        //
        // POST: /Cuenta/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, Cuenta cuenta)
        {
            if (ModelState.IsValid)
            {
                CuentaRepo.modificarCuenta(cuenta);
                return RedirectToAction("Index");
            }
            return View(cuenta);
        }

        //
        // GET: /Cuenta/Delete/5
 
        public ActionResult Delete(int idCuenta, int idSocio, int estadoActual)
        {
            int nuevoEstado = this.cambiarEstado(estadoActual);

            CuentaUsuario c = CuentaRepo.getSingle(idCuenta, idSocio);
            CuentaRepo.eliminarCuenta(c, nuevoEstado);

            return RedirectToAction("Index");
        }
        private int cambiarEstado(int actual)
        {
            if (actual == 0) return 1 ; else return 0;
        }


        //
        // GET: /Cuenta/LogOn

        public ActionResult LogOn()
        {
            //Fijarse si ya hay una cookie de usuario, i.e. si el usuario ya esta logueado.
            LogOnModel logOnModel = new LogOnModel();

            HttpCookie existingCookie = Request.Cookies["userName"];
            if (existingCookie != null)
            {
                logOnModel.UserName = existingCookie.Value;
            }

            return View(logOnModel);
        }

        //
        // POST: /Cuenta/LogOn

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                //Si valida los campos con un usuario existente
                bool valida = false;

                Cuenta cta = (from u in db.Cuentas
                              join p in db.CuentaUsuarios on u.IdCuenta equals p.Cuenta
                             where u.Usuario.Equals(model.UserName) &&
                                   u.Password.Equals(model.Password)
                             select u).FirstOrDefault();

                if (cta == null)
                {
                    // Invalid user name or password
                }
                else
                {   
                    //Hace el join para determinar si la cuenta esta activa
                    CuentaUsuario activa = (from u in db.Cuentas
                                            join p in db.CuentaUsuarios on u.IdCuenta equals p.Cuenta
                                            where u.Usuario.Equals(model.UserName) &&
                                                  u.Password.Equals(model.Password)
                                            select p).FirstOrDefault();

                    if (activa.Activada != 1)
                    {
                        // La cuenta esta desactivada
                        ModelState.AddModelError("", "La cuenta esta desactivada por los administradores.");
                        valida = false;
                    }
                    else
                    {
                        // Exito
                        valida = true;
                    }
                }
                if (valida)
                {

                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }


                else
                {
                    ModelState.AddModelError("", "El usuario o password ingresado es incorrecto.");
                }
            }

            // Si llegamos hasta acá es porque hubo algún error, mostrar nuevamente el form
            return View(model);
        }

        //
        // GET: /Cuenta/LogOff

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Account/Register

        public ActionResult Register()
        {
            return View();
        }

        //
        // POST: /Account/Register

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePassword

        [Authorize]
        public ActionResult ChangePassword()
        {
            return View();
        }

        //
        // POST: /Account/ChangePassword

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {

                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                    changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePasswordSuccess

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "User name already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }
        #endregion
    

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
